/**
 * 用 GPIO 口模拟 SPI 接口驱动
 */

#include "simspi.h"

#define sclk(level) (dev->sclk(level))
#define mosi(level) (dev->mosi(level))
#define miso()      (dev->miso())
#define delay()		mcu_clock_us_delay(dev->delay_us)

uint8_t unidrv_simspi_trx1(unidrv_simspi_t *dev, uint8_t ch) {
	uint8_t inch = 0;

	for(uint8_t i=0; i<8; i++) {
		sclk(0); delay();	// SCLK 低时发送数据
		mosi(ch & 0x80);	// 发送数据(MSB:高位在前)
		ch <<= 1;			// 准备发送下一个bit(MSB:高位在前)
		
		sclk(1); delay();	// SCLK 高时接收数据(MSB:高位在前)
		inch <<= 1;			// 准备接收当前bit(MSB:高位在前)
		inch += miso();		// 接收当前bit
	}

	return inch;
}

std_err_t unidrv_simspi_trx(unidrv_simspi_t *dev, uint8_t *tx, uint8_t *rx, size_t nbyte) {
	if(!dev || !nbyte) return STD_ERR_INVALID_ARG;
	uint8_t ch;

	dev->csn(0);
	for(size_t i=0; i < nbyte; i++) {
		ch = tx ? tx[i] : 0xFF;
		ch = unidrv_simspi_trx1(dev, ch);
		if(rx) rx[i] = ch;
	}
	dev->csn(1);
	return STD_ERR_OK;
}
